package com.qf.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.qf.cache.CategoryCache;
import com.qf.enums.CheckType;
import com.qf.events.CategoryCacheChangeEvent;
import com.qf.exceptions.AddDataErrorException;
import com.qf.exceptions.MyBaseException;
import com.qf.exceptions.MyErrorCode;
import com.qf.exceptions.UpdateDataErrorException;
import com.qf.mapper.SysCategoryMapper;
import com.qf.pojo.SysCategory;
import com.qf.pojo.SysUserInfo;
import com.qf.service.SysCategoryService;
import com.qf.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * created by 赵文韬 on 2022/3/18 19:25
 */
//spring创建类，声明事务
    @Service
    @Transactional
public class SysCategoryServiceImpl implements SysCategoryService {
    //声明一个spring的全局变量ApplicationContext对象,并注入
    private ApplicationContext applicationContext;
    @Autowired
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }
    //声明缓存对象并注入
    private CategoryCache categoryCache;
    @Autowired
    public void setCategoryCache(CategoryCache categoryCache) {
        this.categoryCache = categoryCache;
    }
    //声明mapper对象并注入
    private SysCategoryMapper sysCategoryMapper;
    @Autowired
    public void setSysCategoryMapper(SysCategoryMapper sysCategoryMapper) {
        this.sysCategoryMapper = sysCategoryMapper;
    }

    @Override
    public void addSysCategory(SysCategory sysCategory) {
    //检查数据是不是传递了,没有传递就抛异常
        Assert.isTrue(!sysCategory.isEmpty(CheckType.ADD), ()->{
            throw new AddDataErrorException("分类名称没有传递", MyErrorCode.DATA_NULL);
        });
        //检查当前是不是登录用户，如何判断用户登录了，从session中获取
       /* SysUserInfo loginUser = SecurityUtils.getLoginWithTest();
        Assert.notNull(loginUser, ()->{
            throw new AddDataErrorException("未登录",MyErrorCode.NOT_LOGIN );
        });
        //补充CrestBy
        sysCategory.setCreateBy(loginUser.getUsername());*/
        //补充CreateTime
        sysCategory.setCreateTime(new Date());
        //把对象添加入数据库
        sysCategoryMapper.addSysCategory(sysCategory);
        //发布一个事件通知缓存更新
        applicationContext.publishEvent(new CategoryCacheChangeEvent());

    }


    @Override
    @Transactional(readOnly = true)
    public SysCategory findById(Long id) {
        //查询是从缓存中查询的
        /*SysCategory sysCategory = categoryCache.get(id);*/
        /*SysCategory sysCategory = sysCategoryMapper.findById(id);*/
        SysCategory sysCategory = categoryCache.get(id);
        return sysCategory;
    }

    @Override
    public PageInfo<SysCategory> findByPage(int pageNum, int pageSize, String categoryName) {
        PageHelper.startPage(pageNum, pageSize);
        //先用条件过滤到一部分数据, 然后以剩下的数据做分页
        //SELECT * FROM XXX WHERE XXXX LIKE %ASDAD% LIMIT 1,1
        List<SysCategory> categoryList = categoryCache.getCategoryListCache();

//        ArrayList<Object> arrayList = new ArrayList<>();//保存有符合过滤条件的数据
//        for (SysCategory sysCategory : categoryList) {
//            if (!StringUtils.hasText(categoryName)||sysCategory.getCategoryName().contains(categoryName)) {//包含指定条件的数据保存起来
//                arrayList.add(sysCategory);
//            }
//        }
        //拿到所有和关键字匹配的数据
        List<SysCategory> categories = categoryList.stream().filter(sysCategory -> {
            //如果传值了就代表判断数据是否包含,如果没有,就直接返回true就是所有的数据都要
            return StringUtils.hasText(categoryName) ? sysCategory.getCategoryName().contains(categoryName) : true;
        }).collect(Collectors.toList());

        //这是当前页要的数据,这个数据要从符合过滤条件中的数据来拿
        List<SysCategory> realList = categories.stream().skip((pageNum - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
        //将数据保存到pageinfo中
        PageInfo<SysCategory> pageInfo = new PageInfo<>(realList);
        pageInfo.setTotal(categories.size());//设置的是符合条件的所有的数据
        pageInfo.setPageSize(pageSize);
        pageInfo.setPageNum(pageNum);

        return pageInfo;
    }

    @Override
    public int sysCategoryUpdate(SysCategory sysCategory) {
        //传递的对象非空验证
        Assert.isTrue(!sysCategory.isEmpty(CheckType.UPDATE),()->{
            throw new UpdateDataErrorException("数据不能为空", MyErrorCode.DATA_NULL);
        } );
        //判断有没有登录
        SysUserInfo loginUser = SecurityUtils.getLoginUser();
        Assert.notNull(loginUser,()->{
            throw new AddDataErrorException("请先登录",MyErrorCode.NOT_LOGIN );
        } );
        //设置其他数据
        sysCategory.setUpdateTime(new Date());
        sysCategory.setCreateBy(loginUser.getUsername());
        int update = sysCategoryMapper.update(sysCategory);
        applicationContext.publishEvent(new CategoryCacheChangeEvent());
        return update;
    }

    @Override
    public int deleteById(List<Long> cid) {
        //传递的参数不能为空
        Assert.notEmpty(cid,()->{
            throw new MyBaseException("未传递主键",MyErrorCode.DATA_NULL);
        } );
        //查看用户是否登录
        SysUserInfo loginUser = SecurityUtils.getLoginUser();
        Assert.notNull(loginUser, ()->{
            throw new MyBaseException("请先登录",MyErrorCode.NOT_LOGIN );
        });
        int result = sysCategoryMapper.delete(cid);
        //更新缓存
        applicationContext.publishEvent(new CategoryCacheChangeEvent());
        return result;
    }




























    /*@Override
    public PageInfo<SysCategory> fingByPage(int pageNum, int pageSize,String categoryName) {
        PageHelper.startPage(pageNum,pageSize);
        *//*List<SysCategory> categoryListCache = categoryCache.getCategoryListCache();
        categoryListCache.stream().filter(sysCategory -> {
            return StringUtils.hasText(categoryName)?sysCategory.getCategoryName().contains(categoryName):true;
        }).collect(Collectors.toList());
        List<SysCategory> collect = categoryListCache.stream().skip((pageNum - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
        //将数据保存到pageinfo中*//*
        *//*List<SysCategory> categoryList = categoryCache.getCategoryListCache();*//*
        List<SysCategory> categoryList = sysCategoryMapper.findAll();
        categoryList.stream().filter(sysCategory -> {
            return StringUtils.hasText(categoryName)?sysCategory.getCategoryName().contains(categoryName):true;
        }).collect(Collectors.toList());
        List<SysCategory> collect = categoryList.stream().skip((pageNum - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
        PageInfo<SysCategory> sysCategoryPageInfo = new PageInfo<>(collect);
        sysCategoryPageInfo.setTotal(categoryList.size());
        sysCategoryPageInfo.setPageSize(pageSize);
        sysCategoryPageInfo.setPageNum(pageNum);
        *//*System.err.println(categoryList);
        PageInfo<SysCategory> pageInfo = new PageInfo<>(categoryList);*//*


       *//*ArrayList<Object> arrayList = new ArrayList<>();//保存有符合过滤条件的数据
       for (SysCategory sysCategory : categoryList) {
            if (!StringUtils.hasText(categoryName)||sysCategory.getCategoryName().contains(categoryName)) {//包含指定条件的数据保存起来
                arrayList.add(sysCategory);
            }
        }
        PageInfo pageInfo = new PageInfo(arrayList);
        *//**//*sysCategoryPageInfo.setTotal(categoryListCache.size());*//**//*
        pageInfo.setPageSize(pageSize);
        pageInfo.setPageNum(pageNum);*//*
        return sysCategoryPageInfo;
    }*/
}
